这题居然只有 $luogu$ 有……无法水多倍经验了(逃。
朴素的 $\rm{DP}$ 很简单,设 $f_{i,j}$ 表示前 $i$ 个村庄建了 $j$ 个基站的花费最小值,注意因为是前 $i$ 个,所有完全无视掉后面的所有村庄了。转移的话直接枚举一个 $k$ ,从 $f_{k,j-1}$ 转移过来即可,加上的代价就是中间村庄产生的补偿费用。
那么这样的复杂度就是 $O(n^2k)$ [爆炸] ,我们需要做到的就是如何快速计算中间村庄的补偿,那么外围的 $\rm{DP}$ 复杂度其实是 $O(nk)$ 的,如果中间的补偿可以快速算出那么就可以过掉了。
我们对于每一个村庄 $i$ ,用二分计算出最左边可以覆盖到其的村庄 $st_i$ 和最右边可以覆盖到其的村庄 $ed_i$ ,那么我们从 $i$ 到 $i+1$ 的时候,所有 $ed$ 值为 $i$ 的点都将失去右边的依靠,这个时候对于 $i+1$ 的最优转移点 $k$ ,有对于一个失去”右边依靠”的村庄 $j$ ,如果 $k$ 的范围在 $[1,st_j-1]$ 之间的话那么就要给 $j$ 补偿了。
于是我们考虑用线段树优化,对于这样一个村庄 $j$ ,我们在 $[1,st_j-1]$ 区间集体加上 $w_j$ ,表示决策点如果落在那个区间就要多付出 $w_j$ 的费用。
线段树的每个位置维护的就是 $f_k+$ $i$ 和 $k$ 中间村庄的补偿费用,因为我们每一次的答案就是整个区间的 $\min$ 值了,只是随着 $i$ 的变化线段树维护的值也应当做出变化,所以就会向上面那样更新。
不过有个问题,有个情况没有考虑道:第 $n$ 个村庄不建基站的情况,对于一个小于 $n$ 的 $i$ ,$f_i$ 管不了 $n$ ,那么 $f_n$ 也仅仅表示 $n$ 建站的情况。
所以我们需要在 $n+1$ 的位置上建一个辅助基站,当然 $c_{n+1}=0$ ,这样子就很好计算 第 $n$ 个村庄不建站时全局的花费了
。
Code:
1 |
|
本文标题:【题解】 [ZJOI2010]基站选址 线段树优化DP luoguP2065
文章作者:Qiuly
发布时间:2019年05月09日 - 00:00
最后更新:2019年05月09日 - 22:43
原始链接:http://qiulyblog.github.io/2019/05/09/[题解]luoguP2605/
许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。